package com.example.fridaykt.service.impl

import cn.dev33.satoken.stp.SaLoginConfig
import cn.dev33.satoken.stp.StpUtil
import cn.hutool.core.map.MapUtil
import com.example.fridaykt.common.result.R
import com.example.fridaykt.model.*
import com.example.fridaykt.repository.SysMenuRepository
import com.example.fridaykt.repository.SysRoleRepository
import com.example.fridaykt.repository.SysUserRepository
import com.example.fridaykt.service.SysUserService
import com.example.fridaykt.utils.CryptoUtil
import com.example.fridaykt.vo.Page
import com.example.fridaykt.vo.UserVO
import org.babyfish.jimmer.sql.kt.ast.expression.*
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import org.springframework.util.StringUtils
import java.util.*

/**
 * @author 27371
 * @description 针对表【sys_user(用户信息表)】的数据库操作Service实现
 * @createDate 2022-05-09 17:22:17
 */
@Service
@Transactional
class SysUserServiceImpl(
    private val cryptoUtil: CryptoUtil,
    private val sysMenuRepository: SysMenuRepository,
    private val sysRoleRepository: SysRoleRepository,
    private val sysUserRepository: SysUserRepository,
) : SysUserService {
    override fun login(username: String, password: String): R {
        if (!StringUtils.hasText(username) || !StringUtils.hasText(password)) {
            return R.error(50000, "用户名或密码不能为空")
        }
        val user = sysUserRepository.sql.createQuery(SysUser::class) {
            where(table.userName eq username)
            select(table)
        }.fetchOneOrNull()

        if (Objects.isNull(user)) {
            return R.error(50000, "用户不存在")
        }
        if (!user!!.password.equals(cryptoUtil.encrypt(password))) {
            return R.error(50000, "密码错误")
        }
        val userId = user.userId.toString()
        StpUtil.login(
            "login:$userId", SaLoginConfig
                .setExtra("name", username)
                .setExtra("userId", userId)
        )
        val jwt = StpUtil.getTokenValue()
        return R.success(
            "登录成功", MapUtil.builder<String, Any>(HashMap<String, Any>())
                .put("userName", user.userName)
                .put("name", user.nickName)
                .put("name", user.nickName)
                .put("token", jwt)
                .build()
        )
    }

    override fun logout(): R {
        val userid = StpUtil.getLoginIdDefaultNull() as String
        if (Objects.isNull(userid)) {
            return R.error(50000, "用户未登录")
        }
        StpUtil.logout()
        return R.success("注销成功")
    }

    override fun getUserList(uservo: UserVO): Page<SysUser> {
        val cur = uservo.current ?: 0
        val ps = uservo.pageSize ?: 10

        val res = sysUserRepository.sql.createQuery(SysUser::class) {
            where += table.userId `eq?` uservo.userId

            uservo.userName?.takeIf { it.isNotEmpty() }?.let {
                where += table.userName ilike it
            }
            uservo.nickName?.takeIf { it.isNotEmpty() }?.let {
                where += table.nickName ilike it
            }
            uservo.userType?.takeIf { it.isNotEmpty() }?.let {
                where += table.userType eq it
            }
            uservo.email?.takeIf { it.isNotEmpty() }?.let {
                where += table.email eq it
            }
            uservo.phonenumber?.takeIf { it.isNotEmpty() }?.let {
                where += table.phonenumber eq it
            }
            uservo.sex?.takeIf { it.isNotEmpty() }?.let {
                where += table.sex eq it
            }
            if (Objects.nonNull(uservo.startLoginDate) && Objects.nonNull(uservo.endLoginDate)) {
                where += table.loginDate ge uservo.startLoginDate!!
                where += table.loginDate le uservo.endLoginDate!!
            }
            uservo.createBy?.takeIf { it.isNotEmpty() }?.let {
                where += table.createBy eq it
            }
            uservo.remark?.takeIf { it.isNotEmpty() }?.let {
                where += table.remark ilike it
            }
            select(table)
        }.fetchPage(cur - 1, ps)

        return Page<SysUser>().apply {
            current = cur
            pageSize = ps
            records = res.rows
            total = res.totalPageCount
        }
    }

    override fun getRoleListById(id: Long): List<SysRole> {
        return sysRoleRepository.sql.createQuery(SysRole::class) {
            where(table.sysUsers {
                userId eq id
            })
            select(table)
        }.execute()
    }

    override fun getMenuIdsByUserId(id: Long): List<Long> {
        return sysMenuRepository.sql.createQuery(SysMenu::class) {
            where(table.sysRoles {
                sysUsers {
                    userId eq id
                }
            })
            select(table.menuId)
        }.execute()
    }
}




